/*
 * bw_net_cfg.c
 *
 *  Created on: 2018年10月9日
 *  Author: Degang.Wu (windragon@126.com)
 *  Desc:
 */

#include <stdio.h>
#include <stdlib.h>
#include<sys/stat.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <string.h>
#include <ifaddrs.h>

#include "bw_net_cfg.h"
#include "bw_net_type.h"
#include "version.h"

#define 	NETWORK_CFG		"/etc/network/interfaces"
#define 	HWMAC_ADDR_LEN	6

#define		ADDR_IP		"address"
#define		MASK_IP		"netmask"
#define		GATE_IP		"gateway"
#define		HW_MAC	    "hwaddress ether"

int file_exist(const char *fname)
{
	struct stat buf;
	return stat(fname, &buf) ? 0 : 1;
}

int cfg_get_by_key(char *file, char* ethname,char *key, char *value, int value_len)
{
	FILE *fp = NULL;
	int eth_line = 0;
	char file_str[1024]={0};
	int line_len = 0;
	char buf[1024] = {0};
	unsigned int eth_flg = 0;

	if(!file || !ethname || !key || !value)
	{
		return -1;
	}
	
	fp = fopen(file,"r+");//创建的文件
	if(fp==NULL)
	{
		return -1;
	}

	while(fgets(file_str,sizeof(file_str),fp))
	{
		//line++;
		line_len = strlen(file_str);		
		//len += line_len;	
		
		//首先定位网卡
		snprintf(buf,sizeof(buf),"auto %s",ethname);
		if( strstr(file_str,buf))
		{
			eth_flg = 1;
		}
		
		if(0 == eth_flg)
		{
			continue;
		}
		
		eth_line++;
		
		if(1 == eth_flg)
		{
			if(strstr(file_str,key))  
			{
				snprintf(buf,sizeof(buf),"%s ",key);//address 192.168.1.1
				if(file_str[line_len - 1] == '\n')
				{
					file_str[line_len - 1] = '\0';//换行符
				}
				snprintf(value,value_len,"%s",file_str + strlen(buf));
		
				break;
			}
		}
		
		if(eth_line > 6)//限制
		{
			break;
		}
	}
	
	fclose(fp);
	return 0;
}

int cfg_set_by_key(char *file, char* ethname,char *key, char *value)
{
	FILE *fp = NULL;	//文件指针
	int eth_line = 0;
	char file_str[1024];
	int len = 0;
	int line_len = 0;
	char buf[1024] = {0};
	char buf_end[2*1024] = {0};
	unsigned int eth_flg = 0;

	if(!file || !ethname || !key || !value)
	{
		return -1;
	}
	
	fp = fopen(file,"r+");//创建的文件
	if(fp==NULL)
	{
		//printf("open error\n");
		return -1;
	}

	while(fgets(file_str,sizeof(file_str),fp))//逐行循环读取文件，直到文件结束 
	{
		line_len = strlen(file_str);		
		len += line_len;	
		
		//首先定位网卡
		snprintf(buf,sizeof(buf),"auto %s",ethname);
		if( strstr(file_str,buf))
		{
			eth_flg = 1;
		}
		
		if(0 == eth_flg)
		{
			continue;
		}
		
		eth_line++;
		
		if(1 == eth_flg)
		{
			if(strstr(file_str,key))  
			{
				//保存尾部
				fseek(fp, len, SEEK_SET);
				fread(buf_end,1,sizeof(buf_end),fp);
				
				len -= line_len;//行首
				snprintf(buf,sizeof(buf),"%s ",key);				
				len += strlen(buf);//跳过头
				
				fseek(fp, len, SEEK_SET);	//定位
				fprintf(fp, "%s\n", value);	//换行符保证后面的在新行
				
				//写入保存的尾部
				fwrite(buf_end,1,sizeof(buf_end),fp);//sizeof保证清除没用的数据
				
				break;
			}
		}
		
		if(eth_line > 6)//限制
		{
			break;
		}
	}
	
	fclose(fp);//关闭文件，结束
	return 0;
}

//设置路由表
BW_RT set_route_table(S32 set_type, S32 eth_id, S8 *eth_name, S8 *eth_ip,
		S8 *eth_gw, S8 *netmask);

const char* bw_net_get_version()
{
	return VERSION_NUMBER;
}

static int bw_net_mac2str(char* byte, int byte_len, char* strbuf, int buf_len)
{
	if (byte_len < 6 || buf_len < 6)
	{
		return -1;
	}
	snprintf(strbuf, buf_len, "%02x:%02x:%02x:%02x:%02x:%02x",
			byte[0] & 0xff, byte[1] & 0xff, byte[2] & 0xff,
			byte[3] & 0xff, byte[4] & 0xff, byte[5] & 0xff);
	return 0;
}
/*
 * 检查网卡名是否合法（是否为本机中的网卡名）
 * 合法返回1，不合法返回0
 */
int bw_net_exist_interface(const char* ethname)
{
	int ret = 0;
	int sfd, if_count, i;
	struct ifconf ifc;
	struct ifreq ifr[10];

	if (!ethname)
	{
		return 0;
	}

	memset(&ifc, 0, sizeof(struct ifconf));

	sfd = socket(AF_INET, SOCK_STREAM, 0);

	ifc.ifc_len = 10 * sizeof(struct ifreq);
	ifc.ifc_buf = (char *) ifr;

	ioctl(sfd, SIOCGIFCONF, (char *) &ifc);

	if_count = ifc.ifc_len / (sizeof(struct ifreq));
	for (i = 0; i < if_count; i++)
	{
		if (0 == strcmp(ifr[i].ifr_name, "lo"))
		{
			continue;
		}
		if (0 == strcmp(ifr[i].ifr_name, ethname))
		{
			ret = 1;
			break;
		}
	}

	close(sfd);

	return ret;
}

/*
 * 从接口上获取ip地址
 * 成功返回0， 失败返回-1
 */
int bw_net_get_interface_ipaddr(const char* ethname, char* buf, int buflen)
{
	int sfd, if_count, i;
	struct ifconf ifc;
	struct ifreq ifr[10];
	char ipaddr[INET_ADDRSTRLEN] =
	{ '\0' };
	int ret = -1;

	if (!buf)
	{
		return -1;
	}

	memset(buf, 0, buflen);

	memset(&ifc, 0, sizeof(struct ifconf));

	sfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sfd < 0)
	{
		return -1;
	}

	ifc.ifc_len = 10 * sizeof(struct ifreq);
	ifc.ifc_buf = (char *) ifr;

	ioctl(sfd, SIOCGIFCONF, (char *) &ifc);

	if_count = ifc.ifc_len / (sizeof(struct ifreq));
	for (i = 0; i < if_count; i++)
	{
		if (0 == strcmp(ifr[i].ifr_name, "lo"))
		{
			continue;
		}
		if (0 == strcmp(ifr[i].ifr_name, ethname))
		{
			inet_ntop(AF_INET,
					&(((struct sockaddr_in *) &(ifr[i].ifr_addr))->sin_addr),
					ipaddr, INET_ADDRSTRLEN);
			snprintf(buf, buflen, "%s", ipaddr);
			ret = 0;
			break;
		}
	}

	close(sfd);

	return ret;
}

/*
 * 从接口获取网络参数：IP，NETMASK，MAC
 * 成功返回0， 失败返回-1
 */
int bw_net_get_interface_param(const char* ethname, pstNetParam pNet)
{
	int sfd, if_count, i;
	struct ifconf ifc;
	struct ifreq ifr[10];
	int ret = -1;

	if (!pNet)
	{
		return -1;
	}
	memset(pNet, 0, sizeof(stNetParam));

	sfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sfd < 0)
	{
		return -1;
	}

	memset(&ifc, 0, sizeof(struct ifconf));
	ifc.ifc_len = 10 * sizeof(struct ifreq);
	ifc.ifc_buf = (char *) ifr;

	if (ioctl(sfd, SIOCGIFCONF, (char *) &ifc) < 0)
	{
		perror("ioctl");
		return -1;
	}

	if_count = ifc.ifc_len / (sizeof(struct ifreq));
	for (i = 0; i < if_count; i++)
	{
//    	printf("%d:%s\n", i, ifr[i].ifr_name);
		if (0 == strcmp(ifr[i].ifr_name, "lo"))
		{
			continue;
		}
		if (0 == strcmp(ifr[i].ifr_name, ethname))
		{
			// interface name
			snprintf(pNet->name, sizeof(pNet->name), "%s", ethname);
			// interface ipaddr
			inet_ntop(AF_INET,
					&(((struct sockaddr_in *) &(ifr[i].ifr_addr))->sin_addr),
					pNet->ipaddr, INET_ADDRSTRLEN);
			// interface netmask
			strcpy(ifr[i].ifr_name, ethname);
			ioctl(sfd, SIOCGIFNETMASK, &ifr[i]);
			inet_ntop(AF_INET,
					&(((struct sockaddr_in *) &(ifr[i].ifr_netmask))->sin_addr),
					pNet->netmask, INET_ADDRSTRLEN);

			// interface mac
			strcpy(ifr[i].ifr_name, ethname);
			ioctl(sfd, SIOCGIFHWADDR, &ifr[i]);
			memcpy(pNet->mac, ifr[i].ifr_hwaddr.sa_data, 6);
			bw_net_mac2str(pNet->mac, sizeof(pNet->mac), pNet->mac_str, sizeof(pNet->mac_str));

			// ethid
			pNet->ethid = bw_net_get_interface_idx(ethname);

			ret = 0;
			break;
		}
	}
	close(sfd);

	return ret;
}

static int bw_net_trim_addr(char* buf, int buflen)
{
	char* head = buf;
	char* tail = buf+strlen(buf)-1;
	char  tmp[1024];
	while (head < tail && (*head == '"' || *head == ' '))
	{
//		printf("++\n");
		head++;
	}
	while (head < tail && (*tail == '"' || *tail == ' '))
	{

//		printf("%c--\n", *tail);
		*tail-- = 0;
	}

	if (tail > head)
	{
		snprintf(tmp, sizeof(tmp), "%s", head);
		snprintf(buf, buflen, "%s", tmp);
	}

	return 0;
}
/*
 * 从配置文件获取网络参数
 * 成功返回0， 失败返回-1
 */
int bw_net_get_cfg_param(const char* ethname, pstNetParam pNet)
{
	char cfg_path[BUF_PATH_LEN];
	if (!pNet)
	{
		return -1;
	}
	memset(pNet, 0, sizeof(stNetParam));

	snprintf(cfg_path, sizeof(cfg_path), "%s", NETWORK_CFG);
	
	if (!file_exist(cfg_path))
	{
		return -1;
	}

	snprintf(pNet->name,sizeof(pNet->name),"%s",ethname);
	
	cfg_get_by_key(cfg_path, (char *)ethname,(char *)ADDR_IP, pNet->ipaddr,sizeof(pNet->ipaddr));
	bw_net_trim_addr(pNet->ipaddr, sizeof(pNet->ipaddr));

	cfg_get_by_key(cfg_path, (char *)ethname,(char *)MASK_IP, pNet->netmask,sizeof(pNet->netmask));
	bw_net_trim_addr(pNet->netmask, sizeof(pNet->netmask));

	cfg_get_by_key(cfg_path, (char *)ethname,(char *)GATE_IP, pNet->gateway,sizeof(pNet->gateway));
	bw_net_trim_addr(pNet->gateway, sizeof(pNet->gateway));

	cfg_get_by_key(cfg_path, (char *)ethname,(char *)HW_MAC, pNet->mac_str,sizeof(pNet->mac_str));
	/*uccfg_get_by_key(cfg_path, (char*) "BOOTPROTO", pNet->bootproto,
			sizeof(pNet->bootproto));
	bw_net_trim_addr(pNet->bootproto, sizeof(pNet->bootproto));
	*/
	
	return 0;
}

int bw_net_getparams(const char* ethname, pstNetParam pNet)
{
	stNetParam np1, np2;
	if (!pNet)
	{
		return -1;
	}

	bw_net_get_interface_param(ethname, &np1);
	//memset(&np1,0,sizeof(stNetParam));
	bw_net_get_cfg_param(ethname, &np2);

	snprintf(pNet->name, sizeof(pNet->name), "%s", np1.name);

	if (strlen(np1.ipaddr) > 0)
	{
		snprintf(pNet->ipaddr, sizeof(pNet->ipaddr), "%s", np1.ipaddr);
	}
	else
	{
		snprintf(pNet->ipaddr, sizeof(pNet->ipaddr), "%s", np2.ipaddr);
	}

	if (strlen(np1.netmask) > 0)
	{
		snprintf(pNet->netmask, sizeof(pNet->netmask), "%s", np1.netmask);
	}
	else
	{
		snprintf(pNet->netmask, sizeof(pNet->netmask), "%s", np2.netmask);
	}

	snprintf(pNet->gateway, sizeof(pNet->gateway), "%s", np2.gateway);

#if 1
	memcpy(pNet->mac, np1.mac, sizeof(pNet->mac));
	memcpy(pNet->mac_str, np1.mac_str, sizeof(pNet->mac_str));
#else
	//memcpy(pNet->mac, np2.mac, sizeof(pNet->mac));
	memcpy(pNet->mac_str, np2.mac_str, sizeof(pNet->mac_str));
#endif

	snprintf(pNet->bootproto, sizeof(pNet->bootproto), "%s", np2.bootproto);

	pNet->ethid = np1.ethid;

	return 0;
}


int bw_net_set_cfg(const char* ethname, char* ipaddr, char* netmask,char* gateway)
{
	int ret = 0;
	char cfg_path[BUF_PATH_LEN];
	char bak_cfg_path[BUF_PATH_LEN];
	char cmd_str[BUF_PATH_LEN];

	if (!bw_net_exist_interface(ethname))
	{
		return -1;
	}

	stNetParam oldParam, newParam;

	//获取当前配置
	bw_net_getparams(ethname, &oldParam);

	snprintf(cfg_path, sizeof(cfg_path), "%s", NETWORK_CFG);
	if (!file_exist(NETWORK_CFG))
	{
		return -1;
	}

	//备份配置文件
	snprintf(bak_cfg_path, sizeof(bak_cfg_path), "%s.bak", cfg_path);
	snprintf(cmd_str, sizeof(cmd_str), "cp -f %s %s", cfg_path, bak_cfg_path);
	system(cmd_str);

	cfg_set_by_key(cfg_path, (char *)ethname,(char*)ADDR_IP, ipaddr);
	cfg_set_by_key(cfg_path, (char *)ethname,(char*)MASK_IP, netmask);
	cfg_set_by_key(cfg_path, (char *)ethname,(char*)GATE_IP, gateway);
	//cfg_set_by_key(cfg_path, (char *)ethname,(char*)"", (char*) "static");	//dhcp可能会导致设置不成功
	//cfg_set_by_key(cfg_path, (char*) "ONBOOT", '=', (char*) "yes");

	//snprintf(cmd_str, sizeof(cmd_str), "%s", "systemctl restart network");
	//system(cmd_str);
	//return 0;

	snprintf(cmd_str, sizeof(cmd_str), "ifconfig %s %s netmask %s", ethname, ipaddr, netmask);
	system(cmd_str);

	//验证新配置是否成功
	bw_net_get_interface_param(ethname, &newParam);

	if (strcmp(newParam.ipaddr, ipaddr))	//与设置的IP不同，恢复旧配置
	{
		ret = -1;

		//ifconfig em1 192.168.1.248 netmask 255.255.255.0
		if (strlen(oldParam.ipaddr) > 0)
		{
			//只设置ip，不重启网络服务
			snprintf(cmd_str, sizeof(cmd_str), "ifconfig %s %s netmask %s", ethname, oldParam.ipaddr, oldParam.netmask);
			system(cmd_str);
		}

		snprintf(cmd_str, sizeof(cmd_str), "cp -f %s %s", bak_cfg_path, cfg_path);
		system(cmd_str);

	}
	else
	{
		snprintf(cmd_str, sizeof(cmd_str),
				"echo 0 > /proc/sys/net/ipv4/conf/%s/rp_filter", ethname);
		system(cmd_str);

		//更新路由信息
//		printf("id=%d\n", oldParam.ethid);
		set_route_table(SET_GW_DEL, oldParam.ethid, (char*) ethname,
				oldParam.ipaddr, oldParam.gateway, oldParam.netmask);

		set_route_table(SET_GW_ADD, oldParam.ethid, (char*) ethname, ipaddr,
				gateway, netmask);
	}

	//删除备份文件
	remove(bak_cfg_path);

	bw_net_init_cfg();

	return ret;
}

/*
 * 获取网卡的index
 * 返回值：-1,失败，表示未找到对应网卡
 * 		  >0 ， index值
 */
int bw_net_get_interface_idx(const char* ethname)
{
	int idx = if_nametoindex(ethname);
	if (idx == 0)
	{
		return -1;
	}
	return idx;
}

int bw_net_update_policy_route(const char* ethname)
{
	stNetParam np;
//	printf("%s\n", ethname);
	if (bw_net_getparams(ethname, &np) < 0)
	{
		return -1;
	}

//	printf("%s, %s, %s\n", np.ipaddr, np.netmask, np.gateway);
	if (strlen(np.ipaddr) > 0 && strlen(np.netmask) > 0)
	{
		int idx = bw_net_get_interface_idx(ethname);

		set_route_table(SET_GW_DEL, idx, (char*) ethname, np.ipaddr, np.gateway,
				np.netmask);

		set_route_table(SET_GW_ADD, idx, (char*) ethname, np.ipaddr, np.gateway,
				np.netmask);
	}
	return 0;
}

/*
 * 网络配置初始化：
 * 1）初始化策略路由
 */
int bw_net_init_cfg()
{
	int sfd, if_count, i;
	struct ifconf ifc;
	struct ifreq ifr[10];
	char cmd_str[BUF_PATH_LEN];

	memset(&ifc, 0, sizeof(struct ifconf));

	sfd = socket(AF_INET, SOCK_STREAM, 0);

	ifc.ifc_len = 10 * sizeof(struct ifreq);
	ifc.ifc_buf = (char *) ifr;

	ioctl(sfd, SIOCGIFCONF, (char *) &ifc);

	if_count = ifc.ifc_len / (sizeof(struct ifreq));
	for (i = 0; i < if_count; i++)
	{
		if (0 == strcmp(ifr[i].ifr_name, "lo") || strstr(ifr[i].ifr_name, ":"))
		{
			continue;
		}
		snprintf(cmd_str, sizeof(cmd_str),
				"echo 0 > /proc/sys/net/ipv4/conf/%s/rp_filter",
				ifr[i].ifr_name);
		system(cmd_str);
		bw_net_update_policy_route(ifr[i].ifr_name);
	}

	close(sfd);
	return 0;
}

void bw_net_set_igmp(eIGMPVer ver)
{
	if (ver < BW_NET_IGMP_DEFAULT || ver >= BW_NET_IGMP_NB)
	{
		return;
	}

	int sfd, if_count, i;
	struct ifconf ifc;
	struct ifreq ifr[10];
	char cmd_str[BUF_PATH_LEN];

	memset(&ifc, 0, sizeof(struct ifconf));

	sfd = socket(AF_INET, SOCK_STREAM, 0);

	ifc.ifc_len = 10 * sizeof(struct ifreq);
	ifc.ifc_buf = (char *) ifr;

	ioctl(sfd, SIOCGIFCONF, (char *) &ifc);

	if_count = ifc.ifc_len / (sizeof(struct ifreq));
	for (i = 0; i < if_count; i++)
	{
		if (0 == strcmp(ifr[i].ifr_name, "lo") || strstr(ifr[i].ifr_name, ":"))
		{
			continue;
		}
		//echo "2" > /proc/sys/net/ipv4/conf/enp4s0/force_igmp_version
		snprintf(cmd_str, sizeof(cmd_str),
				"echo %d > /proc/sys/net/ipv4/conf/%s/force_igmp_version",
				ver, ifr[i].ifr_name);
		system(cmd_str);
	}

	close(sfd);
}

int bw_net_set_mac(const char* ethname, const char* mac)
{
	//ifconfig eth0 hw ether 00:0C:18:EF:FF:ED
	if (!bw_net_exist_interface(ethname))
	{
		return -1;
	}
	if (!mac)
	{
		return -1;
	}
	
	char cmd_str[BUF_LEN_512];
	snprintf(cmd_str, sizeof(cmd_str), "ifconfig %s down; ifconfig %s hw ether %s; ifconfig %s up",ethname, ethname, mac, ethname);
	system(cmd_str);

	//写入配置文件
	char cfg_path[BUF_PATH_LEN];
	snprintf(cfg_path, sizeof(cfg_path), "%s", NETWORK_CFG);
	if (file_exist(cfg_path))
	{
		cfg_set_by_key(cfg_path, (char *)ethname,(char*)HW_MAC, (char*)mac);
	}

	return 0;
}

/*
 * 只在set_route_table中使用
 * （以下代码从历史代码中移植过来）
 */
static BW_RT bw_error_print(S8* file, S32 line, BW_RT state)
{
	return state;
}

//全局的子网掩码，为了set-gw函数的子网掩码的参数
U8 SET_DEFAULT_FLAG;
#define TABLE_NAME(id)	(((id)+1)*10)		//定义路由表的名字
#define TABLE_MAIN	255						//定义传参的意思

BW_RT set_route_table(S32 set_type, S32 eth_id, S8 *eth_name, S8 *eth_ip,
		S8 *eth_gw, S8 *netmask)
{
	S8 val_buf[255] = "";
	S32 i, check_mask[4], net_gw[4];
	U32 temp_get_mask, all_net = 0, net_gw_32, check_mask_32;
	U32 rtval = BW_OK, tmp_val;

	if (NULL == eth_name || (netmask == NULL) || (eth_gw == NULL))
		return bw_error_print(__FILE__, __LINE__, BW_ERROR);

	tmp_val = sscanf(eth_gw, "%d.%d.%d.%d", net_gw + 3, net_gw + 2, net_gw + 1,
			net_gw + 0);
	if (tmp_val != 4)
		return BW_ERROR;

	tmp_val = sscanf(netmask, "%d.%d.%d.%d", check_mask + 3, check_mask + 2,
			check_mask + 1, check_mask + 0);
	if (tmp_val != 4)
		return BW_ERROR;

	check_mask_32 = ((*(check_mask + 3)) << 24) + ((*(check_mask + 2)) << 16)
			+ ((*(check_mask + 1)) << 8) + ((*(check_mask + 0)) << 0);
	net_gw_32 = ((*(net_gw + 3)) << 24) + ((*(net_gw + 2)) << 16)
			+ ((*(net_gw + 1)) << 8) + ((*(net_gw + 0)) << 0);

	all_net = check_mask_32 & net_gw_32;
	temp_get_mask = check_mask_32;
	i = 0;
	while (temp_get_mask & 0x80000000)
	{
		temp_get_mask = temp_get_mask << 1;
		i++;
	}
	if (temp_get_mask > 0)
		rtval |= bw_error_print(__FILE__, __LINE__, BW_ERROR);

	if (SET_GW_DEL == set_type)
	{
		sprintf(val_buf, "ip route del %u.%u.%u.%u/%d dev %s src %s table %d",
				*((U8*) &all_net + 3), *((U8*) &all_net + 2),
				*((U8*) &all_net + 1), *((U8*) &all_net + 0), i, eth_name,
				eth_ip, TABLE_NAME(eth_id));
		//dbg_print("val_buf=[%s]\n",val_buf);
		tmp_val = system(val_buf);
		if (tmp_val != 0)
			bw_error_print(__FILE__, __LINE__, tmp_val);

		sprintf(val_buf, "ip route del default via %s dev %s table %d", eth_gw,
				eth_name, TABLE_NAME(eth_id));
		//dbg_print("val_buf=[%s]\n",val_buf);
		tmp_val = system(val_buf);
		if (tmp_val != 0)
			bw_error_print(__FILE__, __LINE__, tmp_val);

		sprintf(val_buf, "ip rule  del from %s table %d", eth_ip,
				TABLE_NAME(eth_id));
		system(val_buf);

		//sprintf(val_buf, "route del -net %u.%u.%u.%u netmask %s dev %s ", *((U8*)&all_net+3),*((U8*)&all_net+2),*((U8*)&all_net+1),*((U8*)&all_net+0),netmask, eth_name);
	}
	else if (SET_GW_ADD == set_type)
	{
		sprintf(val_buf, "ip route add %u.%u.%u.%u/%d dev %s src %s table %d",
				*((U8*) &all_net + 3), *((U8*) &all_net + 2),
				*((U8*) &all_net + 1), *((U8*) &all_net + 0), i, eth_name,
				eth_ip, TABLE_NAME(eth_id));
		//dbg_print("val_buf=[%s]\n",val_buf);
		tmp_val = system(val_buf);	//添加table路由
		if (tmp_val != 0)
			bw_error_print(__FILE__, __LINE__, tmp_val);

		sprintf(val_buf, "ip route add default via %s dev %s table %d", eth_gw,
				eth_name, TABLE_NAME(eth_id));
		//dbg_print("val_buf=[%s]\n",val_buf);
		tmp_val = system(val_buf);
		if (tmp_val != 0)
			bw_error_print(__FILE__, __LINE__, tmp_val);

		sprintf(val_buf, "ip rule  add from %s table %d", eth_ip,
				TABLE_NAME(eth_id));
		system(val_buf);

	}
	else
	{
		return bw_error_print(__FILE__, __LINE__, BW_ERROR);
	}

	system("ip route flush cache");
	return rtval;
}
